package com.hibase.core.oss.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hibase.common.constant.FileConstants;
import com.hibase.common.entity.ResponseModel;
import com.hibase.common.exception.HibaseException;
import com.hibase.core.mybatis.service.BaseServiceImpl;
import com.hibase.core.oss.config.OssProperties;
import com.hibase.core.oss.constant.AttaConstant;
import com.hibase.core.oss.entity.Attachment;
import com.hibase.core.oss.entity.vo.AttachmentHelpVO;
import com.hibase.core.oss.entity.vo.FileUploadVO;
import com.hibase.core.oss.mapper.AttachmentMapper;
import com.hibase.core.oss.service.AttachmentService;
import com.hibase.core.oss.util.AliyunOSSUtil;
import com.hibase.core.oss.util.FileUploadCache;
import com.hibase.core.web.annotation.HibaseGetRequestMapping;
import com.hibase.common.exception.HibaseAssert;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 附件表 服务实现类
 * </p>
 *
 * @author hufeng
 * @since 2019-05-20
 */
@Service
@Slf4j
public class AttachmentServiceImpl extends BaseServiceImpl<AttachmentMapper, Attachment> implements AttachmentService {

    @Autowired
    private FileUploadCache fileUploadCache;

    @Autowired
    private OssProperties ossProperties;

    @Override
    public String uploadFile(MultipartFile multipartFile) {

        // 获取文件名
        String fileName = multipartFile.getOriginalFilename();
        // 截取文件名
        int index = fileName.lastIndexOf(".");
        String suffix = fileName.substring(index);
        // 白名单
        List<String> whiteType = Arrays.asList(AttaConstant.UPLOAD_WHITE_TYPE.split(","));

        String fileToken = IdUtil.fastSimpleUUID();

        FileUploadVO fileUploadVO = new FileUploadVO();
        fileUploadVO.setFileType(suffix);
        fileUploadVO.setFileSize(multipartFile.getSize() + "");
        fileUploadVO.setFileName(fileName);

        if (whiteType.contains(suffix.toLowerCase())) {
            try {
                String realName = generateFileName(suffix);
                String realPath = AliyunOSSUtil.BASE_SAVE_PATH
                        .concat(DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN).concat(StrUtil.SLASH))
                        .concat(realName);
                // 上传文件
                String versionId = AliyunOSSUtil.uploadFileStream(ossProperties.getTempBucket(), realPath, multipartFile);
                if (StrUtil.isEmpty(versionId)) {
                    throw new HibaseException("上传文件失败");
                }
                // 读取路径 todo
                fileUploadVO.setFileUrl(realPath);

            } catch (Exception e) {
                e.printStackTrace();
                throw new HibaseException("上传文件失败");
            }
        } else {
            throw new HibaseException("不允许上传" + suffix + "格式文件");
        }
        // 加入缓存
        this.fileUploadCache.addFileToCache(fileToken, fileUploadVO);
//		AttachmentHelpVO attachmentHelpVO = new AttachmentHelpVO();
//		attachmentHelpVO.setBizId("111");
//		attachmentHelpVO.setFileBizType("HIBASE");
//		attachmentHelpVO.setSystemSource("HIBASE"); // 来源
//		List<String> fileTokens = new ArrayList<String>();
//		fileTokens.add(fileToken);
//		attachmentHelpVO.setTokenId(fileTokens);
//		attachmentHelpVO.setDeleteFileIds(null);
//		// 保存附件
//		saveAttachment(attachmentHelpVO);
        return fileToken;
    }

    /**
     * 生成唯一文件名
     *
     * @param suffix 后缀
     * @return 返回文件名
     */
    private String generateFileName(String suffix) throws Exception {
        return DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN).concat("hibase_")
                .concat(IdUtil.fastSimpleUUID()).concat(suffix);
    }

    /**
     * 上传文件
     */
    @Override
    public String uploadFile(MultipartFile multipartFile, FileUploadVO uploadVO) {
        uploadVO.setFileName(multipartFile.getOriginalFilename());
        try {
            return this.uploadFile(multipartFile.getInputStream(), uploadVO);
        } catch (IOException e) {
            e.printStackTrace();
            throw new HibaseException(e);
        }
    }

    @Override
    public String uploadFile(InputStream inputStream, FileUploadVO uploadVO) {
        // 白名单
        List<String> whiteType = Arrays.asList(AttaConstant.UPLOAD_WHITE_TYPE.split(","));
        HibaseAssert.isTrue(CollUtil.contains(whiteType, uploadVO.getFileType().toLowerCase()),
                "上传文件不支持");
        // objectPath
        String objectPath = uploadVO.getFileUrl() + uploadVO.getFileName()+uploadVO.getFileType();
        // 上传文件 保存到 暂存区
        String versionId = AliyunOSSUtil.uploadFileStream(ossProperties.getTempBucket(), objectPath, inputStream);
        if (StrUtil.isEmpty(versionId)) {
            throw new HibaseException("上传文件失败");
        }
        String fileToken = IdUtil.fastSimpleUUID();
        // 加入缓存
        this.fileUploadCache.addFileToCache(fileToken, uploadVO);
        return fileToken;
    }

    @Override
    public List<Attachment> selectByBiz(Attachment query) {

        QueryWrapper<Attachment> wrapper = new QueryWrapper<>();

        boolean beQuery = false;

        if (StrUtil.isNotBlank(query.getBizId())) {
            wrapper.eq("biz_id", query.getBizId());
            beQuery = true;
        }
        if (!beQuery) {
            throw new HibaseException("参数不合法");
        }
        wrapper.eq("file_biz_type", query.getFileBizType());
        if (query.getFileTokens() != null && query.getFileTokens().size() != 0) {
            wrapper.in("file_token", query.getFileTokens());
        }

        return super.list(wrapper);
    }

    @Override
    public List<Attachment> saveAttachment(AttachmentHelpVO attachmentHelpVO) {

        this.deleteAttachment(attachmentHelpVO);

        List<Attachment> tmsAttachments = new ArrayList<>();

        // 插入附件
        if (CollUtil.isNotEmpty(attachmentHelpVO.getTokenId())) {

            for (String fileUuid : attachmentHelpVO.getTokenId()) {

                Attachment tmsAttachment = new Attachment();

                tmsAttachment.setBizId(attachmentHelpVO.getBizId());
                tmsAttachment.setSystemSource(attachmentHelpVO.getSystemSource());
                tmsAttachment.setFileBizType(attachmentHelpVO.getFileBizType());
                // 获取文件信息
                FileUploadVO tmsFileUploadVO = fileUploadCache.getFileToCache(fileUuid);

                if (tmsFileUploadVO == null) {

                    throw new HibaseException("上传的文件已失效，请重新上传");
                }
                AliyunOSSUtil.saveFileObj(ossProperties.getTempBucket(), tmsFileUploadVO.getFileUrl(), null);
                tmsAttachment.setFileName(tmsFileUploadVO.getFileName());
                tmsAttachment.setFileUrl(tmsFileUploadVO.getFileUrl());
                tmsAttachment.setFileType(tmsFileUploadVO.getFileType());
                tmsAttachment.setFileSize(Float.parseFloat(tmsFileUploadVO.getFileSize()));
                tmsAttachment.setFileToken(fileUuid);

                tmsAttachments.add(tmsAttachment);
            }

            super.saveOrUpdateBatch(tmsAttachments);
        }

        return tmsAttachments;
    }

    /**
     * 删除附件
     */
    private void deleteAttachment(AttachmentHelpVO attachmentHelpVO) {

        // 删除附件信息
        if (CollUtil.isNotEmpty(attachmentHelpVO.getDeleteFileIds())) {

//            TmsAttachment delete = new TmsAttachment();
//            for (String id : attachmentHelpVO.getDeleteFileIds()) {
//
//                delete.setId(id);
//                // 修改，删除用户已选择的附件
//                super.deleteBy(delete);
//            }
            super.deleteBy(attachmentHelpVO.getDeleteFileIds());
        }
    }


    /**
     * @param response
     * @param fileName
     * @Title: WmsPoController
     * @Description: Excel模板下载
     * @author TimBrian
     * @since Jun 18, 2021 3:40:06 PM
     */
    @ApiOperation(value = "下载PO模板")
    @HibaseGetRequestMapping(value = "linkPoTemplate")
    public Object linkPoTemplate(HttpServletResponse response, String fileName) {

        ClassPathResource resource = new ClassPathResource(FileConstants.TEMPLATE_URL + File.separator + fileName);
        String filename = resource.getFilename();
        try {
            HibaseAssert.notNull(filename, "获取文件名失败");
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                    .header(HttpHeaders.CONTENT_DISPOSITION,
                            "attachment; filename=\"" + URLEncoder.encode(filename, "UTF-8") + "\"")
                    .body(resource);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return ResponseModel.successMsg();
    }

    /**
     * (non-Javadoc)
     * <p>Title: linkTemplate</p>
     * <p>Description: Excel模板下载</p>
     *
     * @param response
     * @param fileName
     * @return
     * @throws UnsupportedEncodingException
     * @author TimBrian
     * @see com.hibase.core.oss.service.AttachmentService#linkTemplate(javax.servlet.http.HttpServletResponse, java.lang.String)
     * @since Jun 23, 2021 2:15:18 PM
     */
    @Override
    public Object linkTemplate(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
        ClassPathResource resource = new ClassPathResource(FileConstants.TEMPLATE_URL + File.separator + fileName);
        String filename = resource.getFilename();
        HibaseAssert.notNull(filename, "get fileName is fail");
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + URLEncoder.encode(filename, "UTF-8") + "\"")
                .body(resource);
    }

    /**
     * (non-Javadoc)
     * <p>Title: selectFileListByTokens</p>
     * <p>Description: 根据fileTokens获取图片列表</p>
     *
     * @param transform
     * @return
     * @author TimBrian
     * @see com.hibase.core.oss.service.AttachmentService#selectFileListByTokens(com.hibase.core.oss.entity.Attachment)
     * @since Jul 29, 2021 5:11:20 PM
     */
    @Override
    public List<Attachment> selectFileListByTokens(Attachment transform) {

        boolean beQuery = false;
        if (transform.getFileTokens() != null && transform.getFileTokens().size() != 0) {
            beQuery = true;
        }
        if (!beQuery) {
            throw new HibaseException("参数不合法");
        }
        return super.list(Wrappers.<Attachment>lambdaQuery().in(Attachment::getFileToken, transform.getFileTokens()));

    }
}
